/**
 * Copyright (c) 2010, Todd Ginsberg
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *    * Neither the name of Todd Ginsberg, or Gowalla nor the
 *      names of any contributors may be used to endorse or promote products
 *      derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 *  Also, please use this for Good and not Evil.  
 */
package com.ginsberg.gowalla.dto;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * DTO for full Spot data, as returned from Gowalla.
 * 
 * @author Todd Ginsberg
 */
public class FullSpot extends SimpleSpot implements Locatable {

	private static final long serialVersionUID = 7662308406311793401L;
	private List<Category> spot_categories;
	private String description;
	private String twitter_username;
	private String[] websites;
	private Date created_at;
	private User creator;
	private List<SpotVisitor> top_10;
	private List<User> founders;
	private List<Checkin> last_checkins;
	private boolean merged;
	private int max_items_count;
	private GeoPoint geoLocation;
	private Address address;
	private int highlights_count;
	private String foursquare_id;
	private String yelp_url;

	public FullSpot() {
		super();
	}

	@Override
	public GeoPoint getGeoLocation() {
		if (geoLocation == null) {
			geoLocation = new GeoPoint(lat, lng);
		}
		return geoLocation;
	}

	/**
	 * Was this spot merged into another? Meaning: even though you asked for one
	 * spot, are you really getting another?
	 * 
	 * @return boolean true if the spot was merged, false if not.
	 */
	public boolean isMerged() {
		return merged;
	}

	public void setMerged(boolean merged) {
		this.merged = merged;
	}

	public List<Category> getCategories() {
		return spot_categories;
	}

	public void setCategories(List<Category> categories) {
		this.spot_categories = categories;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getTwitterUsername() {
		return twitter_username;
	}

	public void setTwitterUsername(String twitter_username) {
		this.twitter_username = twitter_username;
	}

	public String[] getWebsites() {
		return websites;
	}

	public void setWebsites(String[] websites) {
		this.websites = websites;
	}

	public Date getCreatedAt() {
		return created_at;
	}

	public void setCreatedAt(Date created_at) {
		this.created_at = created_at;
	}

	public User getCreator() {
		return creator;
	}

	public void setCreator(User creator) {
		this.creator = creator;
	}

	public List<SpotVisitor> getTop10() {
		return top_10;
	}

	public void setTop10(List<SpotVisitor> top10) {
		this.top_10 = top10;
	}

	public List<User> getFounders() {
		return founders;
	}

	public void setFounders(List<User> founders) {
		this.founders = founders;
	}

	public List<Checkin> getCheckins() {
		return last_checkins;
	}

	public void setCheckins(List<Checkin> last_checkins) {
		this.last_checkins = last_checkins;
	}

	public int getMaxItemsCount() {
		return max_items_count;
	}

	public void setMaxItemsCount(int maxItemsCount) {
		this.max_items_count = maxItemsCount;
	}

	public int getHighlights_count() {
		return highlights_count;
	}

	public void setHighlights_count(int highlightsCount) {
		highlights_count = highlightsCount;
	}

	public String getFoursquareId() {
		return foursquare_id;
	}

	public void setFoursquareId(String foursquareId) {
		foursquare_id = foursquareId;
	}

	public String getYelpUrl() {
		return yelp_url;
	}

	public void setYelpUrl(String yelpUrl) {
		yelp_url = yelpUrl;
	}

	/**
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result + ((address == null) ? 0 : address.hashCode());
		result = prime * result
				+ ((created_at == null) ? 0 : created_at.hashCode());
		result = prime * result + ((creator == null) ? 0 : creator.hashCode());
		result = prime * result
				+ ((description == null) ? 0 : description.hashCode());
		result = prime * result
				+ ((founders == null) ? 0 : founders.hashCode());
		result = prime * result 
				+ ((last_checkins == null) ? 0 : last_checkins.hashCode());
		result = prime * result
				+ ((foursquare_id == null) ? 0 : foursquare_id.hashCode());
		result = prime * result
				+ ((geoLocation == null) ? 0 : geoLocation.hashCode());
		result = prime * result + highlights_count;
		result = prime * result + max_items_count;
		result = prime * result + (merged ? 1231 : 1237);
		result = prime * result
				+ ((spot_categories == null) ? 0 : spot_categories.hashCode());
		result = prime * result + ((top_10 == null) ? 0 : top_10.hashCode());
		result = prime
				* result
				+ ((twitter_username == null) ? 0 : twitter_username.hashCode());
		result = prime * result + Arrays.hashCode(websites);
		result = prime * result
				+ ((yelp_url == null) ? 0 : yelp_url.hashCode());
		return result;
	}

	/**
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!super.equals(obj))
			return false;
		if (getClass() != obj.getClass())
			return false;
		FullSpot other = (FullSpot) obj;
		if (address == null) {
			if (other.address != null)
				return false;
		} else if (!address.equals(other.address))
			return false;
		if (created_at == null) {
			if (other.created_at != null)
				return false;
		} else if (!created_at.equals(other.created_at))
			return false;
		if (creator == null) {
			if (other.creator != null)
				return false;
		} else if (!creator.equals(other.creator))
			return false;
		if (description == null) {
			if (other.description != null)
				return false;
		} else if (!description.equals(other.description))
			return false;
		if (founders == null) {
			if (other.founders != null)
				return false;
		} else if (!founders.equals(other.founders))
			return false;
		if (last_checkins == null) {
			if (other.last_checkins != null) 
				return false;
		} else if (!last_checkins.equals(other.last_checkins)) 
			return false;
		if (foursquare_id == null) {
			if (other.foursquare_id != null)
				return false;
		} else if (!foursquare_id.equals(other.foursquare_id))
			return false;
		if (geoLocation == null) {
			if (other.geoLocation != null)
				return false;
		} else if (!geoLocation.equals(other.geoLocation))
			return false;
		if (highlights_count != other.highlights_count)
			return false;
		if (max_items_count != other.max_items_count)
			return false;
		if (merged != other.merged)
			return false;
		if (spot_categories == null) {
			if (other.spot_categories != null)
				return false;
		} else if (!spot_categories.equals(other.spot_categories))
			return false;
		if (top_10 == null) {
			if (other.top_10 != null)
				return false;
		} else if (!top_10.equals(other.top_10))
			return false;
		if (twitter_username == null) {
			if (other.twitter_username != null)
				return false;
		} else if (!twitter_username.equals(other.twitter_username))
			return false;
		if (!Arrays.equals(websites, other.websites))
			return false;
		if (yelp_url == null) {
			if (other.yelp_url != null)
				return false;
		} else if (!yelp_url.equals(other.yelp_url))
			return false;
		return true;
	}

	/**
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return String
				.format(
						"FullSpot [address=%s, created_at=%s, creator=%s, description=%s, founders=%s, last_checkins=%s, foursquare_id=%s, geoLocation=%s, highlights_count=%s, " +
						"max_items_count=%s, merged=%s, spot_categories=%s, top_10=%s, twitter_username=%s, websites=%s, yelp_url=%s, checkins_count=%s, " +
						"items_count=%s, photos_count=%s, trending_level=%s, users_count=%s, lat=%s, lng=%s, radius_meters=%s, strict_radius=%s, id=%s, " +
						"image_url=%s, name=%s, url=%s]",
						address, created_at, creator, description, founders, last_checkins,
						foursquare_id, geoLocation, highlights_count,
						max_items_count, merged, spot_categories, top_10,
						twitter_username, Arrays.toString(websites), yelp_url,
						checkins_count, items_count, photos_count,
						trending_level, users_count, lat, lng, radius_meters,
						strict_radius, id, image_url, name, url);
	}

}
